#ifndef _CUE_H_
#define _CUE_H_

struct Cue 
{
	int num;

	enum Num
	{
		NONE,

		STATIC,
		DOOR0 = STATIC,
		DOOR1,
		DOOR2,
		BREAK,
		SECRET_XL,
		SECRET_XXL,
		SECRET_XXXL,
		BOSSROOM,

		PLAYER = 0x10,
		CP1,
		CP2,
		CP3,
		PET,
		PETCP1,
		PETCP2,
		PETCP3,

		ENEMY = 0x20,

		ITEM = 0x40,

		BOAT = 0x60,

		CUECT
	};

	Cue(int n = NONE)
	{
		num = n;
	}

	int Num() const
	{
		return num < 0 ? -num : num;
	}

	float Dir() const
	{
		return num < 0 ? -1 : 1;
	}

	void Face(int face)
	{
		num = Num();
		if (face < 0)
			num = -num;
	}

	bool IsValid() const
	{
		return Num() > NONE && Num() < CUECT;
	}

	bool IsDoor() const
	{
		return DOOR0 <= Num() && Num() <= DOOR2;
	}

	bool IsSecret() const
	{
		return SECRET_XL <= Num() && Num() <= SECRET_XXXL;
	}

	bool IsPlayer() const
	{
		return PLAYER <= Num() && Num() < ENEMY;
	}

	bool IsEnemy() const
	{
		return ENEMY <= Num() && Num() < ITEM;
	}

	bool IsItem() const
	{
		return ITEM <= Num() && Num() < BOAT;
	}

	bool IsBoat() const
	{
		return BOAT <= Num() && Num() < CUECT;
	}

	int TypeN(int classn) const
	{
		return Num() - classn;
	}
};

#include "grid.hpp"

struct cJSON;

class Image;

class CueGrid
{
public:
	bool Open(const std::string & name);
	bool Save(const std::string & name);
	void Close();

	int Cols()
	{
		return cues.Cols();
	}

	int Rows()
	{
		return cues.Rows();
	}

	void Put(int c, int r, std::string & name, int face);
	void Put(int c, int r, const Cue & cue)
	{
		cues.Put(c, r, (short)cue.num);
	}

	Cue Get(int c, int r)
	{
		return Cue((short)cues.Get(c, r));
	}

	void Erase(int c, int r)
	{
		cues.Put(c, r, Cue::NONE);
	}

	void Draw(Image & cueimg);

	void Resize(int cols, int rows)
	{
		cues.Resize(cols, rows);
	}

private:
	Grid cues;
};

extern CueGrid Cues;

#endif
